package visitorpattern;

import java.util.LinkedList;

import bookworm.Book;
import bookworm.CalculatesRatingsBookworm;
import bookworm.CreateBooksBasedOnReviews;
import bookworm.Review;

import graph.BookReviewNode;

public class BooksFromSpecificAuthorVisitor implements Visitor
{
	private LinkedList<Book> booksFromAuthor; //the books can have tags different from specificTag
	private LinkedList<Book> booksFromAuthorAndSpecificTag;
	private String authorName;
	private LinkedList<Review> reviewsFromAuthor;
	private LinkedList<Review> reviewsFromAuthorFromSpecificTag;
	private String specificTag;
	
	public BooksFromSpecificAuthorVisitor(String authorName, String specificTag)
	{
		this.reviewsFromAuthor = new LinkedList<Review>();
		this.reviewsFromAuthorFromSpecificTag = new LinkedList<Review>();
		this.authorName = authorName;
		this.specificTag = specificTag;
	}
	
	public LinkedList<Book> getBooksFromAuthor() 
	{
		if(this.booksFromAuthor == null)
		{
			this.booksFromAuthor =
					CreateBooksBasedOnReviews.createBooksFromReviews(reviewsFromAuthor);
		}
		return booksFromAuthor;
	}
	
	public LinkedList<Book> getBooksFromAuthorAndSpecificTag()
	{
		if(this.booksFromAuthorAndSpecificTag == null)
		{
			this.createBooksFromAuthorAndSpecificTag();
		}
		
		return this.booksFromAuthorAndSpecificTag;
	}
	
	private void createBooksFromAuthorAndSpecificTag()
	{
		this.booksFromAuthorAndSpecificTag = 
				CreateBooksBasedOnReviews.createBooksFromReviews(reviewsFromAuthorFromSpecificTag);
	}

	@Override
	public void visitBookReviewNode(BookReviewNode nodeVisited) 
	{
		Review reviewFromNode = nodeVisited.getReviewData();
		LinkedList<String> authorsFromNode = reviewFromNode.getAuthors();
		for(int i = 0; i < authorsFromNode.size(); i++)
		{
			String oneAuthor = authorsFromNode.get(i);
			if(oneAuthor.compareToIgnoreCase(this.authorName) == 0)
			{
				/*it's a review from the specified author*/
				this.reviewsFromAuthor.add(reviewFromNode);
				
			    /*now let's see if it's related to the tag too*/
				LinkedList<String> tagsFromReview = reviewFromNode.getTags();
				for(int j = 0; j < tagsFromReview.size(); j++)
				{
					String oneTag = tagsFromReview.get(j);
					if(oneTag.compareToIgnoreCase(this.specificTag) == 0)
					{
						//so the review has the specified author and tag
						this.reviewsFromAuthorFromSpecificTag.add(reviewFromNode);
					}
				}
			}
		}
	}
	
	/**
	 * i'll get the average rating of that author based on the books written by him. But
	 * i'll check only the books from specified tag.
	 * At the end, we'll know if the author was a good "romance" writer or "horror" writer... etc.
	 * @return
	 */
	public int getAverageRatingOfAuthorBasedOnSpecificTag()
	{
		//maybe the books weren't created yet. But we have the reviews
		this.createBooksFromAuthorAndSpecificTag();
		
		int ratingOfAuthorBasedOnTag = 
				CalculatesRatingsBookworm.calculateAverageRatingOfAuthorBasedOnSpecificTag
															(this.booksFromAuthorAndSpecificTag);
		return ratingOfAuthorBasedOnTag;
	}
}
